﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IRCPhase2Tester.Daemons;
using IRCPhase2Tester.Client;

namespace IRCPhase2Tester.Tests
{
    public abstract class MultiClientsMultiDaemons : ITest
    {
        protected List<Daemons.DaemonBase> daemons;
        protected List<Client.Client> clients;

        public MultiClientsMultiDaemons()
        {
            this.daemons = new List<Daemons.DaemonBase>();
            this.clients = new List<Client.Client>();
        }

        #region ITest Members

        protected void StartNewDaemon(int nodeId, string configuration, Type daemonType)
        {
            DaemonBase daemon = null;

            if (daemonType == typeof(ExternalRoutingDaemon))
            {
                daemon = new ExternalRoutingDaemon(nodeId, configuration);
            }
            else
            {
                daemon = new LocalRoutingDaemon(nodeId, configuration);
            }

            this.daemons.Add(daemon);

            int attempts = 5;
            while (attempts-- > 0)
            {
                try
                {
                    daemon.Start();
                    break;
                }
                catch
                {
                    System.Threading.Thread.Sleep(2000);
                }
            }

        }

        protected void StartNewClient(int tcpPort)
        {
            Client.Client client = null;

            int attempts = 5;

            while (attempts-- > 0)
            {
                try
                {
                    client = new Client.Client(tcpPort);
                    this.clients.Add(client);
                    break;
                }
                catch
                {
                    System.Threading.Thread.Sleep(2000);
                }
            }
        }

        public virtual void BuildUp()
        {
            System.Threading.Thread.Sleep(5000);
        }

        public abstract bool RunTest();

        public virtual void TearDown()
        {
            foreach (Client.Client client in this.clients)
            {
                try
                {
                    client.Close();
                }
                catch
                {
                }
            }

            foreach (DaemonBase daemon in this.daemons)
            {
                try
                {
                    daemon.Suspend();
                    daemon.Kill();
                }
                catch
                {
                }
            }
        }

        public virtual int NumberOfMinutes()
        {
            return 3;
        }

        public abstract string Title();

        public virtual string Description()
        {
            return string.Empty;
        }

        public virtual string ExpectedOutput()
        {
            return string.Empty;
        }

        #endregion
    }
}
